package com.isoft.service.impl;

import com.isoft.entity.DfmeCaneEntity;
import com.isoft.mapper.DfmeCaneMapper;
import com.isoft.service.DfmeCaneService;
import com.isoft.util.XmlParserUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class DfmeCaneServiceImpl implements DfmeCaneService {
    private static final Logger logger = LoggerFactory.getLogger(DfmeCaneServiceImpl.class);
    private static final DateTimeFormatter DATE_TIME_FORMATTER =
            DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    // 默认状态值列表
    private static final List<String> DEFAULT_ALLOWED_STATUSES = Arrays.asList(
            "SCHEDULED", "PLANNED", "CONFIRMED", "ACTIVE", "NEW", "CREATED"
    );

    private final DfmeCaneMapper dfmeCaneMapper;
    private final XmlParserUtil xmlParserUtil;
    private final List<String> allowedStatuses;

    @Autowired
    public DfmeCaneServiceImpl(DfmeCaneMapper dfmeCaneMapper, XmlParserUtil xmlParserUtil) {
        this.dfmeCaneMapper = dfmeCaneMapper;
        this.xmlParserUtil = xmlParserUtil;
        this.allowedStatuses = determineAllowedStatuses();
        logger.info("允许的航班状态值: {}", allowedStatuses);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String parseAndSave(MultipartFile file) throws IOException {
        try {
            logger.info("处理航班取消文件: {}, 大小: {} 字节",
                    file.getOriginalFilename(), file.getSize());

            String xmlContent = new String(file.getBytes(), StandardCharsets.UTF_8);
            return parseAndSave(xmlContent);
        } catch (IOException e) {
            logger.error("读取取消文件失败: {}", file.getOriginalFilename(), e);
            throw new IOException("文件读取失败: " + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String parseAndSave(String xmlContent) {
        try {
            if (xmlContent == null || xmlContent.trim().isEmpty()) {
                throw new IllegalArgumentException("XML内容不能为空");
            }

            DfmeCaneEntity entity = xmlParserUtil.parseXml(xmlContent, DfmeCaneEntity.class);
            validateAndPreprocessEntity(entity);
            processCancellationData(entity);

            return String.format("航班取消处理成功. 航班ID: %d",
                    entity.getDflt().getFlightId());
        } catch (Exception e) {
            logger.error("XML解析失败", e);
            throw new RuntimeException("XML处理失败: " + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void parseAndSave(DfmeCaneEntity entity) {
        try {
            validateAndPreprocessEntity(entity);
            processCancellationData(entity);
        } catch (Exception e) {
            logger.error("处理取消实体失败，航班ID: {}",
                    entity.getDflt().getFlightId(), e);
            throw new RuntimeException("取消数据处理失败: " + e.getMessage(), e);
        }
    }

    private List<String> determineAllowedStatuses() {
        try {
            // 尝试从数据库获取约束条件
            String constraint = dfmeCaneMapper.getFlightStatusConstraint();
            if (constraint != null) {
                // 解析约束条件获取允许的状态值
                return parseAllowedStatuses(constraint);
            }

            // 尝试获取一个示例状态
            String sampleStatus = dfmeCaneMapper.getSampleFlightStatus();
            if (sampleStatus != null) {
                // 修复调用 asList 只有一个参数的问题，直接使用 List.of
                return List.of(sampleStatus);
            }
        } catch (Exception e) {
            logger.warn("无法从数据库获取允许的状态值，将使用默认值", e);
        }

        return DEFAULT_ALLOWED_STATUSES;
    }

    private List<String> parseAllowedStatuses(String constraint) {
        // 修正正则表达式，正确转义特殊字符
        Pattern pattern = Pattern.compile("IN\\s*\\(([^)]+)\\)");
        Matcher matcher = pattern.matcher(constraint);

        if (matcher.find()) {
            String values = matcher.group(1);
            return Arrays.stream(values.split(","))
                    .map(s -> s.replaceAll("['\"]", "").trim())
                    .filter(s -> !s.isEmpty())
                    .toList();
        }

        logger.warn("无法从约束条件中解析状态值: {}", constraint);
        return DEFAULT_ALLOWED_STATUSES;
    }

    private void validateAndPreprocessEntity(DfmeCaneEntity entity) {
        if (entity == null || entity.getDflt() == null || entity.getMeta() == null) {
            throw new IllegalArgumentException("无效的取消实体数据");
        }

        if (entity.getDflt().getFlightId() == null) {
            throw new IllegalArgumentException("航班ID不能为空");
        }

        if (entity.getMeta().getDateTime() == null) {
            throw new IllegalArgumentException("日期时间不能为空");
        }

        try {
            LocalDateTime.parse(entity.getMeta().getDateTime(), DATE_TIME_FORMATTER);
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException("无效的日期时间格式，应为 yyyyMMddHHmmss");
        }

        // 设置默认值
        if (entity.getMeta().getSender() == null) entity.getMeta().setSender("");
        if (entity.getMeta().getReceiver() == null) entity.getMeta().setReceiver("");
        if (entity.getMeta().getType() == null) entity.getMeta().setType("");
        if (entity.getMeta().getSubType() == null) entity.getMeta().setSubType("");
    }

    private void processCancellationData(DfmeCaneEntity entity) {
        Long flightId = entity.getDflt().getFlightId();

        try {
            // 1. 检查航班是否存在，不存在则尝试创建
            int flightExists = dfmeCaneMapper.checkFlightExists(flightId);
            if (flightExists == 0) {
                logger.info("航班ID {} 不存在，将尝试自动创建", flightId);
                createFlightWithValidStatus(flightId);
            }

            // 2. 保存消息元数据
            dfmeCaneMapper.insertMeta(entity);
            logger.info("消息元数据保存成功，生成ID: {}", entity.getMeta().getMsgId());

            // 3. 更新航班状态为取消
            int updated = dfmeCaneMapper.updateFlightStatus(entity);
            if (updated == 0) {
                throw new RuntimeException("更新航班状态失败，航班可能不存在");
            }
            logger.info("更新 {} 条航班状态为取消，航班ID: {}", updated, flightId);

            // 4. 保存异常信息
            int inserted = dfmeCaneMapper.insertIrregularity(entity);
            if (inserted == 0) {
                throw new RuntimeException("插入异常数据失败 - 航班可能不存在");
            }
            logger.info("插入 {} 条异常记录，航班ID: {}", inserted, flightId);

        } catch (Exception e) {
            logger.error("处理取消数据失败，航班ID: {}", flightId, e);
            throw new RuntimeException("取消数据处理失败: " + e.getMessage(), e);
        }
    }

    private void createFlightWithValidStatus(Long flightId) {
        // 尝试所有允许的初始状态
        for (String status : allowedStatuses) {
            try {
                int created = dfmeCaneMapper.insertFlightIfNotExists(flightId, status);
                if (created > 0) {
                    logger.info("使用状态 {} 成功创建航班记录，航班ID: {}", status, flightId);
                    return;
                }
            } catch (DataIntegrityViolationException e) {
                logger.debug("使用状态 {} 创建航班记录失败: {}", status, e.getMessage());
                // 继续尝试下一个状态
            }
        }

        // 如果所有状态尝试都失败，检查是否在此期间航班已被创建
        if (dfmeCaneMapper.checkFlightExists(flightId) == 0) {
            throw new RuntimeException("无法创建航班记录: 所有尝试的状态值(" +
                    String.join(",", allowedStatuses) + ")都违反数据库约束");
        } else {
            logger.info("航班ID {} 已由其他进程创建", flightId);
        }
    }
}